
package com.hlkj.pay.app.merchant.ext.impl.leshua.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.leshua.constant.LeshuaPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.LeshuaPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.resp.LeshuaOrderCloseRes;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.resp.LeshuaRefundQueryRes;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.resp.LeshuaTransQueryRes;
import com.hlkj.pay.app.merchant.ext.impl.leshua.dto.resp.LeshuaTransRefundRes;
import com.hlkj.pay.app.merchant.ext.impl.leshua.handler.LeshuaPayCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.yeepay.dto.YeePayAppChannelParams;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.order.RefundOrderDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.MerchantUtils;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 乐刷支付 正扫 反扫 通用处理
 *
 * @author HlpayTeam
 * @date 2024/10/11 16:22
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class LeshuaPaySceneCommonPayOrder {

    @Value("${hlkj.domain}")
    public String domain;

    @Autowired
    private LeshuaPayCommonParamsHandle leshuaPayCommonParamsHandle;

    /**
     * 乐刷支付查询支付订单
     *
     * @param channelPayOrderContext
     */
    public void commonQueryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderContext) {

        CommonResult<LeshuaPayConfig> leshuaPayConfigCommonResult = leshuaPayCommonParamsHandle.leshuaPayConfig(channelPayOrderContext.getProviderChannelConfigDO(),
                channelPayOrderContext.isTest());
        if (!leshuaPayConfigCommonResult.isSuccess()) {
            channelPayOrderContext.setRemark(leshuaPayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        // 支付订单信息
        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        // 商户通道
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        // 乐刷配置信息
        LeshuaPayConfig leshuaPayConfig = leshuaPayConfigCommonResult.getData();
        try {
            YeePayAppChannelParams yeeAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), YeePayAppChannelParams.class);

            Map<String,String> reqData = new HashMap<>();
            reqData.put("service","query_status");
            reqData.put("merchant_id", yeeAppChannelParams.getSubMchId());
            reqData.put("leshua_order_id", payOrderDO.getInsOrderNo());
            log.info("乐刷 订单查询  请求参数 :{}", JsonUtils.toJsonString(reqData));
            String result = leshuaPayCommonParamsHandle.requestPostApi(LeshuaPayConstant.ORDER_GATEWAY_RUL,reqData,leshuaPayConfig);
            log.info("乐刷 订单查询  返回参数 :{}", result);
            if(StrUtil.isEmpty(result)){
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark("乐刷查询支付订单请求失败");
                return;
            }
            // 结果转对象
            LeshuaTransQueryRes transQueryRes = JSONUtil.toBean(result,LeshuaTransQueryRes.class);
            // 通信状态和支付状态都成功
            if("0".equals(transQueryRes.getResp_code()) && "0".equals(transQueryRes.getResult_code())){
                PayOrderDO updartePayOrderDO = new PayOrderDO();
                switch (transQueryRes.getStatus()) {
                    case "0":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                        updartePayOrderDO.setBankMsg("");
                        break;
                    case "2":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                        updartePayOrderDO.setBankMsg("");
                        break;
                    case "6":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                        break;
                    case "8":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.FAIL.getCode());
                        break;
                }

                if (StringUtils.hasText(transQueryRes.getPay_time())) {
                    try {
                        updartePayOrderDO.setSuccessTime(DateUtils.shanghaiDate(transQueryRes.getPay_time(), DatePattern.NORM_DATETIME_PATTERN));
                    }
                    catch (Exception e) {
                        log.error("乐刷订单查询返回 时间格式化错误 dateTime:{},message:{}", transQueryRes.getPay_time(), e.getMessage());
                    }
                }
                updartePayOrderDO.setChannelOrderNo(transQueryRes.getOut_transaction_id());
                updartePayOrderDO.setChannelOrderId(transQueryRes.getChannel_order_id());
                updartePayOrderDO.setInsOrderNo(transQueryRes.getLeshua_order_id());
                if (transQueryRes.getAmount() != null) {
                    updartePayOrderDO.setSettlementAmount(new BigDecimal(leshuaPayCommonParamsHandle.fenToYuan(transQueryRes.getSettlement_amount(),2)));
                    updartePayOrderDO.setPayAmount(new BigDecimal(leshuaPayCommonParamsHandle.fenToYuan(transQueryRes.getAmount(),2)));
                }

                if (StrUtil.isNotEmpty(transQueryRes.getSub_openid())) {
                    updartePayOrderDO.setUserId(transQueryRes.getSub_openid());
                }
                channelPayOrderContext.setUpdartePayOrderDO(updartePayOrderDO);
            }else{
                String respDesc = transQueryRes.getResp_msg();
                if(!"0".equals(transQueryRes.getResult_code())){
                    respDesc = transQueryRes.getError_msg();
                }
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark(respDesc);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("乐刷查询支付订单请求失败 message:{}", e.getMessage(), e);
            channelPayOrderContext.setRemark("乐刷查询支付订单请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    /**
     * 乐刷支付关闭订单
     *
     * @param channelClosePayOrderContext
     */
    public void commonCloseChannelPayOrder(ChannelPayOrderQueryContext channelClosePayOrderContext) {

        CommonResult<LeshuaPayConfig> leshuaPayConfigCommonResult = leshuaPayCommonParamsHandle.leshuaPayConfig(channelClosePayOrderContext.getProviderChannelConfigDO(),
                channelClosePayOrderContext.isTest());
        if (!leshuaPayConfigCommonResult.isSuccess()) {
            channelClosePayOrderContext.setRemark(leshuaPayConfigCommonResult.getMsg());
            channelClosePayOrderContext.setProcessStatus(false);
            return;
        }
        // 支付订单信息
        PayOrderDO payOrderDO = channelClosePayOrderContext.getPayOrderDO();
        // 商户通道
        MerchantAppChannelDO merchantAppChannelDO = channelClosePayOrderContext.getMerchantAppChannelDO();
        // 乐刷配置信息
        LeshuaPayConfig leshuaPayConfig = leshuaPayConfigCommonResult.getData();
        try {
            YeePayAppChannelParams yeeAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), YeePayAppChannelParams.class);

            Map<String,String> reqData = new HashMap<>();
            reqData.put("service","close_order");
            reqData.put("merchant_id", yeeAppChannelParams.getSubMchId());
            reqData.put("third_order_id", payOrderDO.getPayOrderNo());
            log.info("乐刷 订单关闭  请求参数 :{}", JsonUtils.toJsonString(reqData));
            String result = leshuaPayCommonParamsHandle.requestPostApi(LeshuaPayConstant.ORDER_GATEWAY_RUL,reqData,leshuaPayConfig);
            log.info("乐刷 订单关闭  返回参数 :{}", result);
            if(StrUtil.isEmpty(result)){
                channelClosePayOrderContext.setProcessStatus(Boolean.FALSE);
                channelClosePayOrderContext.setRemark("乐刷关闭订单请求失败");
                return;
            }
            LeshuaOrderCloseRes closeRes = JSONUtil.toBean(result,LeshuaOrderCloseRes.class);
            // 通信状态和支付状态都成功
            if("0".equals(closeRes.getResp_code()) && "0".equals(closeRes.getResult_code())){
                PayOrderDO updartePayOrderDO = new PayOrderDO();

                switch (closeRes.getStatus()){
                    case "0":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                        break;
                    case "2":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                        break;
                    case "6":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                        break;
                    case "8":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.FAIL.getCode());
                        break;
                }
                channelClosePayOrderContext.setUpdartePayOrderDO(updartePayOrderDO);
            }else{
                String respDesc = closeRes.getResp_msg();
                if(!"0".equals(closeRes.getResult_code())){
                    respDesc = closeRes.getError_msg();
                }
                channelClosePayOrderContext.setProcessStatus(Boolean.FALSE);
                channelClosePayOrderContext.setRemark(respDesc);
            }

        }catch (Exception e){
            e.printStackTrace();
            log.error("乐刷关闭订单请求失败 message:{}", e.getMessage(), e);
            channelClosePayOrderContext.setRemark("乐刷关闭订单请求失败,失败信息" + e.getMessage());
            channelClosePayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    /**
     * 乐刷支付查询关闭订单状态
     *
     * @param channelPayOrderQueryContext
     */
    public void
    commonQueryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        PayOrderDO updartePayOrderDO = new PayOrderDO();
        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
        channelPayOrderQueryContext.setUpdartePayOrderDO(updartePayOrderDO);
    }

    /**
     * 乐刷支付订单退款
     *
     * @param channelRefundPayOrderContext
     */
    public void commonRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        CommonResult<LeshuaPayConfig> leshuaPayConfigCommonResult = leshuaPayCommonParamsHandle.leshuaPayConfig(channelRefundPayOrderContext.getProviderChannelConfigDO(),
                channelRefundPayOrderContext.isTest());
        if (!leshuaPayConfigCommonResult.isSuccess()) {
            channelRefundPayOrderContext.setRemark(leshuaPayConfigCommonResult.getMsg());
            channelRefundPayOrderContext.setProcessStatus(false);
            return;
        }
        // 支付订单信息
        PayOrderDO payOrderDO = channelRefundPayOrderContext.getPayOrderDO();
        // 退款信息
        RefundOrderDO refundOrderDO = channelRefundPayOrderContext.getRefundOrderDO();
        // 商户通道
        MerchantAppChannelDO merchantAppChannelDO = channelRefundPayOrderContext.getMerchantAppChannelDO();
        // 乐刷配置信息
        LeshuaPayConfig leshuaPayConfig = leshuaPayConfigCommonResult.getData();
        try {
            YeePayAppChannelParams yeeAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), YeePayAppChannelParams.class);

            Map<String,String> reqData = new HashMap<>();
            reqData.put("service","unified_refund");
            reqData.put("merchant_refund_id",refundOrderDO.getRefundOrderNo());
            reqData.put("refund_amount", leshuaPayCommonParamsHandle.yuanToFen(refundOrderDO.getRefundAmount().toString(),2));
            reqData.put("merchant_id", yeeAppChannelParams.getSubMchId());
            reqData.put("third_order_id", payOrderDO.getPayOrderNo());
            reqData.put("notify_url", channelRefundPayOrderContext.getNotifyUrl());
            log.info("乐刷 订单退款  请求参数 :{}", JsonUtils.toJsonString(reqData));
            String result = leshuaPayCommonParamsHandle.requestPostApi(LeshuaPayConstant.ORDER_GATEWAY_RUL,reqData,leshuaPayConfig);
            log.info("乐刷 订单退款  返回参数 :{}", result);
            if(StrUtil.isEmpty(result)){
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelRefundPayOrderContext.setRemark("乐刷订单退款请求失败");
                return;
            }
            LeshuaTransRefundRes refundRes = JSONUtil.toBean(result,LeshuaTransRefundRes.class);
            // 通信状态和支付状态都成功
            if("0".equals(refundRes.getResp_code()) && "0".equals(refundRes.getResult_code())){
                RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
                switch (refundRes.getStatus()){
                    case "10":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
                        break;
                    case "11":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUND.getCode());
                        updateRefundOrderDO.setActualRefundAmount(new BigDecimal(leshuaPayCommonParamsHandle.fenToYuan(refundRes.getRefund_amount(),2)));
                        if(StrUtil.isNotEmpty(refundRes.getRefund_time())){
                            updateRefundOrderDO.setSuccessTime(DateUtils.shanghaiDate(refundRes.getRefund_time(), DatePattern.NORM_DATETIME_PATTERN));
                        }
                        break;
                    case "12":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                        break;
                }
                channelRefundPayOrderContext.setRefundOrderDO(updateRefundOrderDO);
            }else{
                String respDesc = refundRes.getResp_msg();
                if(!"0".equals(refundRes.getResult_code())){
                    respDesc = refundRes.getError_msg();
                }
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelRefundPayOrderContext.setRemark(respDesc);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("乐刷支付退款请求失败 message:{}", e.getMessage(), e);
            channelRefundPayOrderContext.setRemark("乐刷支付退款请求失败,失败信息" + e.getMessage());
            channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    /**
     * 乐刷支付订单退款状态查询
     *
     * @param channelRefundPayOrderContext
     */
    public void commonQueryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {

        CommonResult<LeshuaPayConfig> leshuaPayConfigCommonResult = leshuaPayCommonParamsHandle.leshuaPayConfig(channelRefundPayOrderContext.getProviderChannelConfigDO(),
                channelRefundPayOrderContext.isTest());
        if (!leshuaPayConfigCommonResult.isSuccess()) {
            channelRefundPayOrderContext.setRemark(leshuaPayConfigCommonResult.getMsg());
            channelRefundPayOrderContext.setProcessStatus(false);
            return;
        }
        // 支付订单信息
        PayOrderDO payOrderDO = channelRefundPayOrderContext.getPayOrderDO();
        // 退款信息
        RefundOrderDO refundOrderDO = channelRefundPayOrderContext.getRefundOrderDO();
        // 商户通道
        MerchantAppChannelDO merchantAppChannelDO = channelRefundPayOrderContext.getMerchantAppChannelDO();
        // 乐刷配置信息
        LeshuaPayConfig leshuaPayConfig = leshuaPayConfigCommonResult.getData();
        try {
            YeePayAppChannelParams yeeAppChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), YeePayAppChannelParams.class);


            Map<String,String> reqData = new HashMap<>();
            reqData.put("service","unified_query_refund");
            reqData.put("merchant_refund_id",refundOrderDO.getRefundOrderNo());
            reqData.put("merchant_id", yeeAppChannelParams.getSubMchId());
            reqData.put("third_order_id", payOrderDO.getPayOrderNo());
            log.info("乐刷 订单退款查询  请求参数 :{}", JsonUtils.toJsonString(reqData));
            String result = leshuaPayCommonParamsHandle.requestPostApi(LeshuaPayConstant.ORDER_GATEWAY_RUL,reqData,leshuaPayConfig);
            log.info("乐刷 订单退款查询  返回参数 :{}", result);
            if(StrUtil.isEmpty(result)){
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelRefundPayOrderContext.setRemark("乐刷订单退款查询请求失败");
                return;
            }
            LeshuaRefundQueryRes refundRes = JSONUtil.toBean(result,LeshuaRefundQueryRes.class);
            // 通信状态和支付状态都成功
            if("0".equals(refundRes.getResp_code()) && "0".equals(refundRes.getResult_code())){
                RefundOrderDO updateRefundOrderDO = new RefundOrderDO();
                switch (refundRes.getStatus()){
                    case "10":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUNDING.getCode());
                        break;
                    case "11":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.REFUND.getCode());
                        updateRefundOrderDO.setActualRefundAmount(MerchantUtils.fenToYuan(refundRes.getRefund_amount()));
                        if(StrUtil.isNotEmpty(refundRes.getRefund_time())){
                            updateRefundOrderDO.setSuccessTime(DateUtils.shanghaiDate(refundRes.getRefund_time(), DatePattern.NORM_DATETIME_PATTERN));
                        }
                        break;
                    case "12":
                        updateRefundOrderDO.setRefundStatus(PayOrderEnums.REFUND_STATUS.FAIL.getCode());
                        break;
                }
                channelRefundPayOrderContext.setRefundOrderDO(updateRefundOrderDO);
            }else{
                String respDesc = refundRes.getResp_msg();
                if(!"0".equals(refundRes.getResult_code())){
                    respDesc = refundRes.getError_msg();
                }
                channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelRefundPayOrderContext.setRemark(respDesc);
            }

        }catch (Exception e){
            e.printStackTrace();
            log.error("乐刷支付查询退款请求失败 message:{}", e.getMessage(), e);
            channelRefundPayOrderContext.setRemark("乐刷支付查询退款请求失败,失败信息" + e.getMessage());
            channelRefundPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }


    public Integer expireMinute(Long time) {
        if (time == null) {
            return 30;
        }
        return (int) (time - System.currentTimeMillis()) / 1000 / 60;
    }


    public String reqTime() {
        return DateUtils.getDateString("yyyyMMddHHmmss");
    }

    public String openapiDomain(boolean test) {
        // 测试环境：https://test.wsmsd.cn/sit/api/v2/mms/openApi/wechatParamConf
        // 生产环境：https://s2.lakala.com/api/v2/mms/openApi/wechatParamConf
        if (test) {
            return "https://test.wsmsd.cn/sit";
        }
        else {
            return "https://s2.lakala.com";
        }
    }
}
